package combinations77

func Another(nums []int, k int) [][]int {
	if len(nums) < k {
		return nil // 如果数量不够了，返回nil // 其实返回[][]int{} 也是可以的，表示没有组合
	}
	if k == 0 {
		// 如果目标数量为0，说明之前已经把所有元素凑齐了，此处返回一个空切片
		// 这里关键是我们要返回一个一维切片还是一个二维切片呢？
		// 这取决于我们下文中使用 Another的方式，Another被定义为多个一维切片的结合，所以此处我们得到一个二维切片，虽然这个二维切片中只有一个元素，且是个空元素
		// 注意，我们还不能直接返回 [][]int{} 这种空切片形式，因为这会导致我们在后续的组合中，无法将当前元素leadNum添加到组合中
		// 这里我们返回一个二维切片，表示当前组合的第一个元素leadNum
		return [][]int{{}} // 表示有组合，但是组合的元素为空
	}
	result := make([][]int, 0) // 定义一个二维切片，存放最终的组合
	// 遍历nums
	for i := 0; i < len(nums); i++ {
		// 当前元素作为组合的第一个元素，最终的组合是一个切片
		leadNum := nums[i]
		// 该组合切片的剩余元素仍然通过相同的方式获得，即从 mums[i+1:] 中获取k-1个元素的方式
		leftNumSet := Another(nums[i+1:], k-1) // 递归必须有跳出条件，返回入口处写跳出条件
		// leftNumSet 是一个二维切片，表示从 nums[i+1:] 中获取k-1个元素的所有组合
		// 将 leadNum 和 leftNumSet 中的每一个切片元素组合成每一个新的切片
		// 如果返回nil是不会进入如下的循环的，所以也就意味着不会产生新的组合
		for item := range leftNumSet {
			completeNumSet := append([]int{leadNum}, leftNumSet[item]...) // 这里的append是将一个一维切片添加到二维切片中
			// 将完整的切片组合添加到最终要返回的切片组合中
			result = append(result, completeNumSet)
		}
	}
	return result
}
